home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
intuisup.lha
/
Intuisup
/
source.lha
/
Gadgets
/
gadgets3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-19
|
29KB
|
921 lines
/* $Revision Header *** Header built automatically - do not edit! ***********
*
* (C) Copyright 1991 by Torsten Jürgeleit
*
* Name .....: gadgets3.c
* Created ..: Thursday 19-Dec-91 20:52:56
* Revision .: 5
*
* Date Author Comment
* ========= ==================== ====================
* 19-Aug-92 Torsten Jürgeleit save old clipping rectangles in
* print_list_view_text()
* 06-Aug-92 Torsten Jürgeleit alternate entry text color in
* print_list_view_text()
* 01-Apr-92 Torsten Jürgeleit any references to gadget data
* via gl_Data removed
* 06-Jan-92 Torsten Jürgeleit added pop up cycle text list
* 28-Dec-91 Torsten Jürgeleit correct output of count gadget value
* if ri_ScreenDepth == 1
* 19-Dec-91 Torsten Jürgeleit Created this file!
*
****************************************************************************
*
* Gadget support routines - part 3
*
* $Revision Header ********************************************************/
/* Includes */
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#ifdef AZTEC_C
#include <functions.h> /* needed for Aztec C - prototypes and pragmas for all Amiga system functions */
#endif
#include <libraries/memwatch.h> /* header file for memory debug link library (Fish 240) - AFTER functions.h */
#include <string.h>
#include "/render/render.h"
#include "/texts/texts.h"
#include "/borders/borders.h"
#include "/language/language.h"
#include "gadgets.h"
#include "imports.h"
/* Refresh full ISUP gadget */
VOID
refresh_gadget(struct ExtendedGadget *egad)
{
struct GadgetList *gl = egad->eg_GadgetList;
if (gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED) {
struct RenderInfo *ri = gl->gl_RenderInfo;
struct Window *win = gl->gl_Window;
struct RastPort *rp = win->RPort;
struct ExtendedGadget *first_egad = egad;
/* Render object text - rendering first because of ghosting by GADGDISABLED */
switch (egad->eg_DataType) {
case GADGET_DATA_TYPE_CYCLE :
print_cycle_text(egad);
break;
case GADGET_DATA_TYPE_COUNT :
print_count_text(egad, TRUE);
break;
case GADGET_DATA_TYPE_LISTVIEW :
print_list_view_text(egad);
break;
}
print_gadget_text(first_egad);
/* Render all gadgets belonging to this ISUP object */
do {
struct Gadget *gad = &egad->eg_Gadget;
UBYTE flags = egad->eg_Flags;
/* Draw additional border or image if any */
if (flags & (EXTENDED_GADGET_FLAG_RENDER_BORDER |
EXTENDED_GADGET_FLAG_RENDER_IMAGE)) {
SHORT left_edge = gad->LeftEdge, top_edge = gad->TopEdge;
if (flags & EXTENDED_GADGET_FLAG_RENDER_BORDER) {
DrawBorder(rp, (struct Border *)egad->eg_Render,
(LONG)left_edge, (LONG)top_edge);
} else {
struct Image *image = (struct Image *)egad->eg_Render;
SHORT xoffset = (first_egad->eg_DataFlags &
GADGET_DATA_FLAG_NO_BORDER ?
IMAGE_HORIZ_OFFSET : IMAGE_HORIZ_OFFSET + 2),
width = gad->Width;
top_edge += (SHORT)(gad->Height - image->Height) / 2;
switch (egad->eg_Type) {
case EXTENDED_GADGET_TYPE_CYCLE :
left_edge += xoffset;
break;
case EXTENDED_GADGET_TYPE_COUNT :
DrawImage(rp, &ri->ri_Images[IMAGE_COUNT_RIGHT],
(LONG)(left_edge + width - image->Width - xoffset),
(LONG)top_edge);
left_edge += xoffset;
break;
default :
left_edge += (SHORT)(width - image->Width) / 2;
break;
}
DrawImage(rp, image, (LONG)left_edge, (LONG)top_edge);
}
}
/* Check if disabled selected toggle select gadget */
if ((gad->Activation & TOGGLESELECT) && (gad->Flags &
(GADGDISABLED | SELECTED)) == (GADGDISABLED | SELECTED)) {
APTR render = gad->GadgetRender;
/* Special refresh to force correct ghosting */
gad->GadgetRender = gad->SelectRender;
gad->Flags &= ~SELECTED;
RefreshGList(gad, win, (LONG)NULL, 1L);
gad->Flags |= SELECTED;
gad->GadgetRender = render;
} else {
/* Normal refresh */
RefreshGList(gad, win, (LONG)NULL, 1L);
}
} while (egad = egad->eg_NextGadget);
}
}
/* Change gadget */
VOID
change_gadget(struct ExtendedGadget *egad)
{
struct GadgetList *gl = egad->eg_GadgetList;
struct Window *win = gl->gl_Window;
struct Gadget *gad = &egad->eg_Gadget;
struct PropInfo *pinfo;
struct MXData *mx;
struct SliderData *sl;
struct CycleData *cy;
struct ScrollerData *sc;
struct ListViewData *lv;
struct PaletteData *pd;
VOID *data = (VOID *)(egad + 1);
ULONG min, max, num, body, pot, flags = egad->eg_DataFlags;
UBYTE displayed = gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED;
USHORT i;
switch (egad->eg_DataType) {
case GADGET_DATA_TYPE_BUTTON :
case GADGET_DATA_TYPE_CHECK :
case GADGET_DATA_TYPE_STRING :
case GADGET_DATA_TYPE_INTEGER :
if (displayed) {
RefreshGList(gad, win, (LONG)NULL, 1L);
}
break;
case GADGET_DATA_TYPE_MX :
mx = data;
max = mx->mx_TextEntries;
num = mx->mx_ActiveEntry;
for (i = 0; i < max; i++) {
gad = &egad->eg_Gadget;
if (i == num) {
gad->Flags |= SELECTED;
if (displayed) {
RefreshGList(gad, win, (LONG)NULL, 1L);
}
} else {
if (gad->Flags & SELECTED) {
gad->Flags &= ~SELECTED;
if (displayed) {
RefreshGList(gad, win, (LONG)NULL, 1L);
}
}
}
egad = egad->eg_NextGadget;
}
break;
case GADGET_DATA_TYPE_SLIDER :
pinfo = (struct PropInfo *)gad->SpecialInfo;
sl = data;
min = sl->sl_Min;
max = (LONG)sl->sl_Max - (LONG)min;
num = (LONG)sl->sl_Level - (LONG)min;
if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
num = max - num; /* if vert slider then maximum is at top */
}
body = calc_prop_body(max + 1, 1L);
pot = calc_prop_pot(max + 1, 1L, num);
if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
if (displayed) {
NewModifyProp(gad, win, (LONG)NULL, (LONG)pinfo->Flags, 0L,
pot, 0L, body, 1L);
} else {
pinfo->VertBody = body;
pinfo->VertPot = pot;
}
} else {
if (displayed) {
NewModifyProp(gad, win, (LONG)NULL, (LONG)pinfo->Flags, pot,
0L, body, 0L, 1L);
} else {
pinfo->HorizBody = body;
pinfo->HorizPot = pot;
}
}
break;
case GADGET_DATA_TYPE_SCROLLER :
pinfo = (struct PropInfo *)gad->SpecialInfo;
sc = data;
min = sc->sc_Visible;
max = sc->sc_Total;
num = sc->sc_Top;
body = calc_prop_body(max, min);
pot = calc_prop_pot(max, min, num);
if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
if (displayed) {
NewModifyProp(gad, win, (LONG)NULL, (LONG)pinfo->Flags, 0L,
pot, 0L, body, 1L);
} else {
pinfo->VertBody = body;
pinfo->VertPot = pot;
}
} else {
if (displayed) {
NewModifyProp(gad, win, (LONG)NULL, (LONG)pinfo->Flags, pot,
0L, body, 0L, 1L);
} else {
pinfo->HorizBody = body;
pinfo->HorizPot = pot;
}
}
break;
case GADGET_DATA_TYPE_CYCLE :
cy = data;
cy->cy_ActiveText = cy->cy_TextArray[cy->cy_ActiveEntry];
if (displayed) {
print_cycle_text(egad);
}
break;
case GADGET_DATA_TYPE_COUNT :
if (displayed) {
print_count_text(egad, TRUE);
}
break;
case GADGET_DATA_TYPE_LISTVIEW :
pinfo = (struct PropInfo *)gad->SpecialInfo;
lv = data;
min = lv->lv_VisibleEntries;
max = lv->lv_ListEntries;
num = lv->lv_TopEntry;
body = calc_prop_body(max, min);
pot = calc_prop_pot(max, min, num);
if (displayed) {
NewModifyProp(gad, win, (LONG)NULL, (LONG)pinfo->Flags, 0L, pot,
0L, body, 1L);
print_list_view_text(egad);
} else {
pinfo->VertBody = body;
pinfo->VertPot = pot;
}
break;
case GADGET_DATA_TYPE_PALETTE :
pd = data;
if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
struct Image *image = (struct Image *)egad->eg_Render;
image->PlaneOnOff = pd->pd_ActiveColor;
if (displayed) {
DrawImage(win->RPort, image, (LONG)(gad->LeftEdge + (SHORT)
(gad->Width - image->Width) / 2), (LONG)(gad->TopEdge +
(SHORT)(gad->Height - image->Height) / 2));
}
}
break;
}
}
/* Change cycle gadget text */
BOOL
change_cycle_gadget(struct ExtendedGadget *egad, ULONG qualifier)
{
struct Window *win = egad->eg_GadgetList->gl_Window;
struct MsgPort *up = win->UserPort;
struct Gadget *gad = &egad->eg_Gadget;
struct CycleData *cy = (struct CycleData *)(egad + 1);
LONG entry, old_entry = cy->cy_ActiveEntry;
ULONG old_idcmp_flags = win->IDCMPFlags;
USHORT delay = MAX_CYCLE_DELAY;
BOOL keepon = TRUE, changed = FALSE;
/* Wait a while before using popup cycle text list */
ModifyIDCMP(win, (LONG)(MOUSEBUTTONS | INTUITICKS));
do {
struct IntuiMessage *msg;
WaitPort(up);
if (msg = (struct IntuiMessage *)GetMsg(up)) {
switch (msg->Class) {
case INTUITICKS :
if (!--delay) {
keepon = FALSE;
}
break;
case MOUSEBUTTONS :
if (msg->Code == SELECTUP) {
keepon = FALSE;
}
break;
}
ReplyMsg((struct Message *)msg);
}
} while (keepon == TRUE);
if (delay) {
LONG max_entry = cy->cy_TextEntries - 1;
/* Get new entry entry by selection next or previous one */
if (qualifier & QUALIFIER_SHIFT) {
if (old_entry > 0) {
entry = old_entry - 1;
} else {
entry = max_entry;
}
} else {
if (old_entry < max_entry) {
entry = old_entry + 1;
} else {
entry = 0;
}
}
} else {
/* Get new entry from pop up cycle text list */
if ((entry = pop_up_cycle_list(egad)) == -1L) {
entry = old_entry;
}
}
ModifyIDCMP(win, old_idcmp_flags);
/* Restore normal cycle gadget state (unselected) */
if ((gad->Flags & GADGHIGHBITS) == GADGHCOMP) {
RefreshGList(gad, win, (LONG)NULL, 1L); /* complement gadget select box */
}
gad->Flags &= ~SELECTED;
RefreshGList(gad, win, (LONG)NULL, 1L);
/* Print new cycle text */
if (entry != old_entry) {
cy->cy_ActiveEntry = entry;
cy->cy_ActiveText = cy->cy_TextArray[entry];
print_cycle_text(egad);
changed = TRUE;
}
return(changed);
}
/* Select cycle entry from pop up cycle list */
STATIC LONG
pop_up_cycle_list(struct ExtendedGadget *egad)
{
struct GadgetList *gl = egad->eg_GadgetList;
struct Window *win = gl->gl_Window;
struct RastPort *backup_rp, *rp = win->RPort;
struct CycleData *cy = (struct CycleData *)(egad + 1);
SHORT yinc, left_edge, top_edge;
USHORT width, height;
LONG entry = -1L;
/* Calc pop up list dimension and position */
width = cy->cy_Width + 2 * CYCLE_POP_XOFFSET;
height = cy->cy_EntryHeight * cy->cy_TextEntries +
2 * CYCLE_POP_YOFFSET;
left_edge = cy->cy_LeftEdge - CYCLE_POP_XOFFSET;
top_edge = cy->cy_TopEdge - CYCLE_POP_YOFFSET;
/* If pop up list doesn't fit downwards then try it upwards */
if ((top_edge + height) > win->Height) {
top_edge -= height - (cy->cy_EntryHeight + 2 * CYCLE_POP_YOFFSET);
yinc = -cy->cy_EntryHeight;
/* If it doesn't fit upwards too then give up */
if (top_edge < 0) {
DisplayBeep(NULL);
}
} else {
yinc = cy->cy_EntryHeight;
}
/* Create bitmap for saving pop up list background */
if (top_edge >= 0 && (backup_rp = create_rast_port(width, height,
(USHORT)rp->BitMap->Depth))) {
struct MsgPort *up = win->UserPort;
struct IntuiText itext, *it = &itext;
BYTE **text = cy->cy_TextArray;
USHORT xpos = left_edge + CYCLE_POP_XOFFSET,
ypos = top_edge + CYCLE_POP_YOFFSET,
detail_pen = win->DetailPen, block_pen = win->BlockPen;
LONG last_entry = -1L;
BOOL keepon = TRUE;
/* Save old cycle list backgound and prepare new one */
ClipBlit(rp, (LONG)left_edge, (LONG)top_edge, backup_rp, 0L, 0L,
(LONG)width, (LONG)height, 0xc0L);
SetDrMd(rp, (LONG)JAM1);
SetAPen(rp, (LONG)detail_pen);
RectFill(rp, (LONG)left_edge, (LONG)top_edge,
(LONG)(left_edge + width - 1), (LONG)(top_edge + height - 1));
SetAPen(rp, (LONG)block_pen);
RectFill(rp, (LONG)(left_edge + 2), (LONG)(top_edge + 1),
(LONG)(left_edge + width - 3), (LONG)(top_edge + height - 2));
SetDrMd(rp, (LONG)COMPLEMENT);
/* Print cycle list text */
it->FrontPen = detail_pen;
it->BackPen = block_pen;
it->DrawMode = JAM1;
it->LeftEdge = xpos;
it->TopEdge = (yinc > 0 ? ypos : ypos + height -
(cy->cy_EntryHeight + 2 * CYCLE_POP_YOFFSET));
it->ITextFont = egad->eg_TextAttr;
it->NextText = NULL;
while (*text) {
it->IText = (UBYTE *)get_language_text(*text++,
gl->gl_LanguageTextArray);
PrintIText(rp, it, 0L, 0L);
it->TopEdge += yinc;
}
/* Wait for release of left mouse button */
do {
struct IntuiMessage *msg;
WaitPort(up);
while (msg = (struct IntuiMessage *)GetMsg(up)) {
SHORT mouse_x = win->MouseX, mouse_y = win->MouseY;
/* Check if mouse pointer is over pop up list entry */
if (mouse_x >= (left_edge + CYCLE_POP_XOFFSET) &&
mouse_x < (left_edge + width - 2 * CYCLE_POP_XOFFSET) &&
mouse_y >= (top_edge + CYCLE_POP_YOFFSET) &&
mouse_y < (top_edge + height - 2 * CYCLE_POP_YOFFSET)) {
LONG new_entry = (yinc > 0 ? (mouse_y - ypos) / yinc :
cy->cy_TextEntries - (mouse_y - ypos) / -yinc - 1);
if (new_entry != last_entry) {
USHORT y;
if (last_entry != -1L) {
/* Unmark last selected entry */
y = ypos + CYCLE_LIST_ENTRY_YPOS(last_entry);
RectFill(rp, (LONG)xpos, (LONG)y, (LONG)(xpos + width -
2 * CYCLE_POP_XOFFSET - 1),
(LONG)(y + cy->cy_EntryHeight - 1));
}
/* Mark selected entry */
y = ypos + CYCLE_LIST_ENTRY_YPOS(new_entry);
RectFill(rp, (LONG)xpos, (LONG)y, (LONG)(xpos + width -
2 * CYCLE_POP_XOFFSET - 1),
(LONG)(y + cy->cy_EntryHeight - 1));
last_entry = new_entry;
}
} else {
if (last_entry != -1L) {
USHORT y = ypos + CYCLE_LIST_ENTRY_YPOS(last_entry);
/* Unmark last selected entry */
RectFill(rp, (LONG)xpos, (LONG)y, (LONG)(xpos + width -
2 * CYCLE_POP_XOFFSET - 1),
(LONG)(y + cy->cy_EntryHeight - 1));
last_entry = -1L;
}
}
if (msg->Class == MOUSEBUTTONS && msg->Code == SELECTUP) {
entry = last_entry;
keepon = FALSE;
}
ReplyMsg((struct Message *)msg);
}
} while (keepon == TRUE);
ClipBlit(backup_rp, 0L, 0L, rp, (LONG)left_edge, (LONG)top_edge,
(LONG)width, (LONG)height, 0xc0L);
free_rast_port(backup_rp, width, height);
}
return(entry);
}
/* Build rast port for saving background of pop up cycle list */
STATIC struct RastPort *
create_rast_port(USHORT width, USHORT height, USHORT depth)
{
struct RastPort *rp;
if (rp = AllocMem((LONG)(sizeof(struct RastPort) + sizeof(struct BitMap)),
(LONG)MEMF_PUBLIC)) {
struct BitMap *bm = (struct BitMap *)(rp + 1);
USHORT i;
/* Init rast port */
InitRastPort(rp);
rp->BitMap = bm;
/* Init bitmap structure and allocate bit planes */
InitBitMap(bm, (LONG)depth, (LONG)width, (LONG)height);
for (i = 0; i < depth; i++) {
if (!(bm->Planes[i] = (PLANEPTR)AllocRaster((LONG)width,
(LONG)height))) {
/* Free bitmap */
for ( ; i > 0; i--) {
FreeRaster(bm->Planes[i], (LONG)width, (LONG)height);
}
FreeMem(rp, (LONG)(sizeof(struct RastPort) +
sizeof(struct BitMap)));
rp = NULL;
break;
}
}
}
return(rp);
}
/* Free rast port for saving background of pop up cycle list */
STATIC VOID
free_rast_port(struct RastPort *rp, USHORT width, USHORT height)
{
struct BitMap *bm = rp->BitMap;
USHORT i, depth = bm->Depth;
for (i = 0; i < depth; i++) {
FreeRaster(bm->Planes[i], (LONG)width, (LONG)height);
}
FreeMem(rp, (LONG)(sizeof(struct RastPort) + sizeof(struct BitMap)));
}
/* Change count gadget value */
VOID
change_count_gadget(struct ExtendedGadget *egad)
{
struct Window *win = egad->eg_GadgetList->gl_Window;
struct MsgPort *up = win->UserPort;
struct Gadget *gad = &egad->eg_Gadget;
struct CountData *co = (struct CountData *)(egad + 1);
LONG min = co->co_Min, max = co->co_Max, count = co->co_Value;
ULONG old_idcmp_flags = win->IDCMPFlags;
USHORT max_delay = MAX_COUNT_DELAY, delay = MAX_COUNT_DELAY;
SHORT count_change, middle = gad->LeftEdge + gad->Width / 2;
BOOL keepon = TRUE;
ModifyIDCMP(win, (LONG)(MOUSEBUTTONS | INTUITICKS));
/* Calc new delay and change value with new mouse pos */
if (win->MouseX > middle) {
count_change = +1;
if (count < max) {
count++;
}
} else {
count_change = -1;
if (count > min) {
count--;
}
}
co->co_Value = count;
print_count_text(egad, TRUE);
/* Change count value depending on mouse position (busy loop) */
do {
struct IntuiMessage *msg;
SHORT mouse_x = win->MouseX;
USHORT distance, new_delay;
/* Calc new delay and change value with new mouse pos */
if (mouse_x > middle) {
distance = mouse_x - middle;
count_change = +1;
} else {
distance = middle - mouse_x;
count_change = -1;
}
if (distance > MAX_COUNT_DISTANCE) {
distance = MAX_COUNT_DISTANCE;
}
new_delay = MAX_COUNT_DELAY - distance / MAX_COUNT_STEP_SIZE;
if (new_delay != max_delay) {
max_delay = delay = new_delay;
}
if (msg = (struct IntuiMessage *)GetMsg(up)) {
switch (msg->Class) {
case INTUITICKS :
if (max_delay) {
/* Delayed change of count value */
if (! --delay) {
if ((count + count_change) >= min &&
(count + count_change) <= max) {
co->co_Value = count += count_change;
print_count_text(egad, TRUE);
}
delay = max_delay;
}
}
break;
case MOUSEBUTTONS :
if (msg->Code == SELECTUP) {
keepon = FALSE;
}
break;
}
ReplyMsg((struct Message *)msg);
}
if (! max_delay) {
/* Undelayed change of count value */
if ((count + count_change) >= min && (count + count_change) <=
max) {
co->co_Value = count += count_change;
print_count_text(egad, TRUE);
timer_delay(0L, MIN_COUNT_DELAY_MICROS);
}
}
} while (keepon == TRUE);
ModifyIDCMP(win, old_idcmp_flags);
/* Restore normal count gadget state (unselected) */
if ((gad->Flags & GADGHIGHBITS) == GADGHCOMP) {
RefreshGList(gad, win, (LONG)NULL, 1L); /* complement gadget select box */
}
gad->Flags &= ~SELECTED;
RefreshGList(gad, win, (LONG)NULL, 1L);
}
/* Delay function - can't use Delay() from DOS (no process) */
VOID
timer_delay(ULONG seconds, ULONG micros)
{
struct MsgPort *port;
struct timerequest *timer;
if (port = CreatePort(NULL, 0L)) {
if (timer = (struct timerequest *)CreateExtIO(port, (LONG)
sizeof(struct timerequest))) {
if (!OpenDevice(TIMERNAME, (LONG)UNIT_VBLANK, (struct IORequest *)
timer, 0L)) {
timer->tr_node.io_Command = TR_ADDREQUEST;
timer->tr_time.tv_secs = seconds;
timer->tr_time.tv_micro = micros;
DoIO((struct IORequest *)timer);
CloseDevice((struct IORequest *)timer);
}
DeleteExtIO((struct IORequest *)timer);
}
DeletePort(port);
}
}
/* Print gadget text */
VOID
print_gadget_text(struct ExtendedGadget *egad)
{
BYTE *text;
if (text = egad->eg_Text) {
struct GadgetList *gl = egad->eg_GadgetList;
struct RenderInfo *ri = gl->gl_RenderInfo;
struct Window *win = gl->gl_Window;
struct RastPort *rp = win->RPort;
struct Gadget *gad = &egad->eg_Gadget;
struct TextAttr *ta = egad->eg_TextAttr;
USHORT flags = (egad->eg_DataFlags &
GADGET_DATA_FLAG_TEXT_COLOR2 ? TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_COLOR2 : TEXT_DATA_FLAG_ABSOLUTE_POS),
left_edge = gad->LeftEdge + egad->eg_TextLeftEdge,
top_edge = gad->TopEdge + egad->eg_TextTopEdge;
if (egad->eg_Flags & EXTENDED_GADGET_FLAG_HOTKEY) {
BYTE *buffer;
LONG len = strlen(text) + 1;
USHORT pos = egad->eg_HotkeyPos;
if (pos < len && (buffer = AllocMem(len, (LONG)MEMF_PUBLIC))) {
BYTE c;
USHORT save_left_edge = left_edge;
/* Print text part before hotkey */
strcpy(buffer, text);
if (pos > 1) {
*(buffer + pos - 1) = '\0';
left_edge += print_text(ri, win, buffer, left_edge,
top_edge, TEXT_DATA_TYPE_TEXT, flags, ta);
}
/* Print and underline hotkey character */
if (pos < (len - 2)) {
c = *(buffer + pos + 1);
*(buffer + pos + 1) = '\0';
}
save_left_edge = left_edge;
left_edge += print_text(ri, win, buffer + pos, left_edge,
top_edge, TEXT_DATA_TYPE_TEXT, flags, ta);
SetDrMd(rp, (LONG)JAM1);
SetAPen(rp, (LONG)(egad->eg_DataFlags &
GADGET_DATA_FLAG_TEXT_COLOR2 ? ri->ri_TextPen2 :
ri->ri_TextPen1));
RectFill(rp, (LONG)save_left_edge, (LONG)(top_edge +
egad->eg_TextFont->tf_YSize), (LONG)(left_edge - 1),
(LONG)(top_edge + egad->eg_TextFont->tf_YSize));
/* Print text part after hotkey */
if (pos < (len - 2)) {
*(buffer + pos + 1) = c;
print_text(ri, win, buffer + pos + 1, left_edge, top_edge,
TEXT_DATA_TYPE_TEXT, flags, ta);
}
FreeMem(buffer, len);
} else {
print_text(ri, win, text, left_edge, top_edge,
TEXT_DATA_TYPE_TEXT, flags, ta);
}
} else {
print_text(ri, win, text, left_edge, top_edge, TEXT_DATA_TYPE_TEXT,
flags, ta);
}
}
}
/* Print cycle text */
VOID
print_cycle_text(struct ExtendedGadget *egad)
{
struct GadgetList *gl = egad->eg_GadgetList;
struct RenderInfo *ri = gl->gl_RenderInfo;
struct Window *win = gl->gl_Window;
struct RastPort *rp = win->RPort;
struct CycleData *cy = (struct CycleData *)
(gl->gl_Gadgets[egad->eg_DataEntry] + 1);
struct TextAttr *text_attr = egad->eg_TextAttr;
struct IntuiText itext;
BYTE *text = get_language_text(cy->cy_ActiveText,
gl->gl_LanguageTextArray);
USHORT flags = (egad->eg_DataFlags &
GADGET_DATA_FLAG_TEXT_COLOR2 ? TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_COLOR2 : TEXT_DATA_FLAG_ABSOLUTE_POS),
left_edge = cy->cy_LeftEdge, top_edge = cy->cy_TopEdge,
width = cy->cy_Width, height = cy->cy_Height;
itext.IText = (UBYTE *)text;
itext.ITextFont = text_attr;
SetDrMd(rp, (LONG)JAM1);
SetAPen(rp, (LONG)ri->ri_BackPen);
RectFill(rp, (LONG)left_edge, (LONG)top_edge, (LONG)(left_edge + width -
1), (LONG)(top_edge + height - 1));
print_text(ri, win, text, left_edge + (SHORT)(width -
IntuiTextLength(&itext)) / 2, top_edge, TEXT_DATA_TYPE_TEXT,
flags, text_attr);
}
/* Print count text */
VOID
print_count_text(struct ExtendedGadget *egad, BOOL print_new)
{
struct GadgetList *gl = egad->eg_GadgetList;
struct RenderInfo *ri = gl->gl_RenderInfo;
struct Window *win = gl->gl_Window;
struct RastPort *rp = win->RPort;
struct CountData *co = (struct CountData *)
(gl->gl_Gadgets[egad->eg_DataEntry] + 1);
struct TextAttr *text_attr = egad->eg_TextAttr;
USHORT type = (egad->eg_DataFlags & GADGET_DATA_FLAG_COUNT_SIGNED_DEC ?
TEXT_DATA_TYPE_NUM_SIGNED_DEC :
TEXT_DATA_TYPE_NUM_UNSIGNED_DEC),
gflags = egad->eg_Gadget.Flags,
tflags = (egad->eg_DataFlags & GADGET_DATA_FLAG_TEXT_COLOR2 ?
TEXT_DATA_FLAG_ABSOLUTE_POS | TEXT_DATA_FLAG_PLACE_LEFT |
TEXT_DATA_FLAG_COLOR2 : TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_PLACE_LEFT),
left_edge = co->co_LeftEdge, top_edge = co->co_TopEdge,
width = co->co_Width, height = co->co_Height;
/* Clear area for new value */
if ((gflags & SELECTED) && (gflags & GADGHIGHBITS) == GADGHCOMP) {
tflags |= TEXT_DATA_FLAG_COMPLEMENT | INTERNAL_TEXT_DATA_FLAG_COUNT;
SetAPen(rp, (LONG)(ri->ri_BackPen ^ ((1 << ri->ri_ScreenDepth) - 1)));
} else {
SetAPen(rp, (LONG)ri->ri_BackPen);
}
SetDrMd(rp, (LONG)JAM1);
RectFill(rp, (LONG)left_edge, (LONG)top_edge,
(LONG)(left_edge + width - 1), (LONG)(top_edge + height - 1));
/* Print new value if requested */
if (print_new) {
print_text(ri, win, (BYTE *)co->co_Value, left_edge + width,
top_edge, type, tflags, text_attr);
}
}
/* Print list view text */
VOID
print_list_view_text(struct ExtendedGadget *egad)
{
struct GadgetList *gl = egad->eg_GadgetList;
struct Window *win = gl->gl_Window;
struct RastPort *rp = win->RPort;
struct Layer *layer = rp->Layer;
struct Region *region;
/* Calc offsets for inner window */
LockLayerRom(layer);
if (region = NewRegion()) {
struct RenderInfo *ri = gl->gl_RenderInfo;
struct Rectangle rect;
struct Region *old_region;
struct ClipRect *old_cliprects;
struct ListViewData *lv = (struct ListViewData *)
(gl->gl_Gadgets[egad->eg_DataEntry] + 1);
struct TextAttr *ta = egad->eg_TextAttr;
struct Node *node = lv->lv_TopNode;
ULONG gflags = egad->eg_DataFlags;
USHORT i, tflags = (gflags & GADGET_DATA_FLAG_TEXT_COLOR2 ?
TEXT_DATA_FLAG_COLOR2 | TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_BACK_FILL : TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_BACK_FILL),
left_edge = lv->lv_LeftEdge, top_edge = lv->lv_TopEdge,
width = lv->lv_Width, height = lv->lv_Height,
entries = lv->lv_ListEntries, visible = lv->lv_VisibleEntries,
entry_height = lv->lv_EntryHeight, top = lv->lv_TopEntry;
/* Create clipping region around list view entry area */
rect.MinX = left_edge;
rect.MaxX = left_edge + width - 1;
rect.MinY = top_edge;
rect.MaxY = top_edge + height - 1;
OrRectRegion(region, &rect);
/* Before installing clipping region save old clipping rectangles */
old_cliprects = layer->_cliprects;
layer->_cliprects = NULL;
old_region = InstallClipRegion(layer, region);
/* Print list view entry text with clipping */
SetDrMd(rp, (LONG)JAM1);
SetAPen(rp, (LONG)ri->ri_BackPen);
for (i = visible; i; i--, top++, top_edge += entry_height) {
if (top < entries) {
BYTE *text = node->ln_Name;
USHORT tflags, text_width;
/* Check for alternate entry text color */
if ((gflags & GADGET_DATA_FLAG_LISTVIEW_ENTRY_COLOR) &&
*text == 1) {
text++;
tflags = (gflags & GADGET_DATA_FLAG_TEXT_COLOR2 ?
TEXT_DATA_FLAG_ABSOLUTE_POS | TEXT_DATA_FLAG_BACK_FILL :
TEXT_DATA_FLAG_COLOR2 | TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_BACK_FILL);
} else {
tflags = (gflags & GADGET_DATA_FLAG_TEXT_COLOR2 ?
TEXT_DATA_FLAG_COLOR2 | TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_BACK_FILL : TEXT_DATA_FLAG_ABSOLUTE_POS |
TEXT_DATA_FLAG_BACK_FILL);
}
/* Print entry text and clear rest of line */
text_width = print_text(ri, win, text, left_edge, top_edge,
TEXT_DATA_TYPE_TEXT, tflags, ta);
if (text_width < width) {
RectFill(rp, (LONG)(left_edge + text_width), (LONG)top_edge,
(LONG)(left_edge + width - 1), (LONG)(top_edge +
entry_height - 1));
}
node = node->ln_Succ;
} else {
break;
}
}
if (i) {
RectFill(rp, (LONG)left_edge, (LONG)top_edge, (LONG)(left_edge +
width - 1), (LONG)(top_edge + i * entry_height - 1));
}
/* Highlite selected entry */
if (gflags & GADGET_DATA_FLAG_LISTVIEW_SHOW_SELECTED) {
USHORT selected = lv->lv_SelectedEntry;
/* Check if visible */
top = lv->lv_TopEntry;
if (selected < entries && selected >= top &&
selected < (top + visible)) {
top_edge = lv->lv_TopEdge + (selected - top) * entry_height;
SetDrMd(rp, (LONG)COMPLEMENT);
RectFill(rp, (LONG)left_edge, (LONG)top_edge, (LONG)(left_edge +
width - 1), (LONG)(top_edge + ta->ta_YSize - 1));
}
}
/* Remove clipping region and restore old clipping rectangles */
InstallClipRegion(layer, old_region);
layer->_cliprects = old_cliprects;
DisposeRegion(region);
}
UnlockLayerRom(layer);
}